#-*- coding: utf-8 -*-

class Node(object):
    """
    Classe représentant un noeud d'une liste chainée.
    Quelques fonctions basiques sont aussi prévues.   
        Celles-ci conviennent également pour des listes circulaires.
    """

    def __init__(self, data=0, next=None):
        """
        >>> Node(42)
        42 -> *
        >>> Node(42, Node(43))
        42 -> 43 -> *
        """
        self.data = data
        self.next = next

    def getTail(self):
        """
        Parcourt la chaîne de noeuds pour retrouver le dernier.
        Version statique : getTail_s()
        >>> x = Node(1, Node(2))
        >>> x.getTail()
        2 -> *
        >>> x = Node(1)
        >>> x.getTail()
        1 -> *
        >>> x = Node(1, Node(2))
        >>> x.next.next = x
        >>> x.getTail()
        2 -> 1 -> *
        """
        p = f = self
        if p==None:
            #méthode appelée sur None...
            return None
        while p.next:
            pr = p
            p = p.next
            if p==f:
                return pr
        return p
    getTail_s = staticmethod(getTail)

    def getSize(self):
        """
        Parcourt la chaîne de noeuds pour les compter.
        Version statique : getSize_s()
        >>> x = Node(1, Node(2))
        >>> x.getSize()
        2
        >>> x = Node(1)
        >>> x.getSize()
        1
        >>> x = Node(1, Node(2))
        >>> x.next.next = x
        >>> x.getSize()
        2
        """
        p = f = self
        if p==None:
            #méthode appelée sur None
            return 0
        ct = 0
        while p:
            ct += 1
            p = p.next
            if p==f: break
        return ct
    getSize_s = staticmethod(getSize)

    def __repr__(self):
        """
        Représente une chaine de noeuds sous la forme 1 -> 2 -> 3 -> *
        Version statique (pour repr. None comme si c'était un Node) : repr_s()
        >>> Node(1, Node(2))
        1 -> 2 -> *
        >>> Node(1)
        1 -> *
        >>> x = Node(1, Node(2))
        >>> x.next.next = x
        >>> x
        1 -> 2 -> *
        """
        p = f = self
        s = ""
        while p:
            s += str(p.data) + " -> "
            p = p.next
            if p==f: break
        return s + "*"
    repr_s = staticmethod(__repr__)

    def __str__(self):
        """
        Représente le contenu d'un noeud sous forme de string.
        >>> print Node(42)
        42
        """
        return str(self.data)


if __name__=='__main__':
    import doctest
    doctest.testmod()
